/*
 * Packet.h
 *
 *  Created on: May 29, 2011
 *      Author: michael
 */

#ifndef RAWDATA_H_
#define RAWDATA_H_

#include <vector>
#include "../Messages/Meta.pb.h"
#include "../Messages/MessageTypes.pb.h"
#include <google/protobuf/message_lite.h>

namespace DerbyServ
{

typedef std::vector<char> RawType;

class RawData
{
public:
	static const size_t META_BYTE_SIZE = 7;
public:
	inline RawData()
	{
		serializedMeta.resize(META_BYTE_SIZE);
	}

	inline RawData(const google::protobuf::MessageLite & message, enum Messages::MessageTypes type)
	{
		serializedMeta.resize(META_BYTE_SIZE);

		std::string str;
		message.SerializeToString(&str);
		data.assign(str.begin(), str.end());

		SetSize(data.size());

		BOOST_ASSERT(Messages::MessageTypes_IsValid(type));
		SetType(type);
	}

	inline int32_t Size() const { return meta.size(); }
	inline enum Messages::MessageTypes Type() const { return meta.type(); }
	inline RawType & SerializedMeta()
	{ BOOST_ASSERT(serializedMeta.size() == META_BYTE_SIZE); return serializedMeta; }

	inline RawType & Data() { return data; }
	inline const RawType & Data() const { return data; }

	inline void SerializeMeta()
	{
		std::string str;
		BOOST_ASSERT(meta.ByteSize() == (int)META_BYTE_SIZE);
		meta.SerializeToString(&str);
		serializedMeta.assign(str.begin(), str.end());
		BOOST_ASSERT(serializedMeta.size() == META_BYTE_SIZE);
	}

	inline void DeserializeMeta()
	{
		BOOST_ASSERT(serializedMeta.size() == META_BYTE_SIZE);
		meta.ParseFromArray(serializedMeta.data(), serializedMeta.size());
		BOOST_ASSERT(meta.ByteSize() == (int)META_BYTE_SIZE);
	}

	inline void Clear()
	{
		meta.Clear();
		data.clear();
	}

private:
	inline void SetSize(int32_t size) { meta.set_size(size); }
	inline void SetType(enum Messages::MessageTypes type) { meta.set_type(type); }
	inline void SetData(const RawType & data) { this->data = data; }


private:
	Messages::Meta meta;
	RawType serializedMeta;
	RawType data;
};


} // namespace

#endif /* RAWDATA_H_ */
